﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;

using UploadManager;
//using StoreClientModule;
using UnityCore;

namespace MBBStoreClient
{
    public partial class frmDailySales : Form
    {
        SynchronizeData sync = new SynchronizeData();
        Threader t = new Threader();
        
        readDetails path = new readDetails();

        DataTable exportSales = new DataTable();
        DataTable exportSaleItems = new DataTable();
        DataTable recordTable = new DataTable();
        DataTable dt = new DataTable();
        
        int curLoaded = 0;
        int cL = 0;
        
        public frmDailySales()
        {
            InitializeComponent();

            btnClose.Click += new EventHandler(btnClose_Click);
            panel2.EnabledChanged += new EventHandler(panel2_EnabledChanged);

            btnLoad.Click += new EventHandler(btnLoad_Click);
            btnPrint.Click += new EventHandler(btnPrint_Click);

            sync.ProcessCompleted += new UnityCore.CoreHandler(sync_ProcessCompleted);
            sync.ProcessError += new UnityCore.CoreHandler(sync_ProcessError);
        }

        void sync_ProcessError(string pcode, string msg)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(msg);
                pnlMsg.Visible = false;
            });
        }
        void sync_ProcessCompleted(string pcode, string msg)
        {
            t.SafeCall(this, delegate
            {
                switch (pcode)
                {
                    case "GetStores":
                        cmbStore.Items.AddRange(sync.stores);
                        break;
                    case "ReadMany":
                        pnlMsg.Visible = true;
                        exportSales = sync.exportTables[0];//.DefaultView.ToTable(true, new string[]{"fSalesman"});
                        DataView dv = exportSales.DefaultView;
                        dv.Sort = "fInvoice";
                        exportSales = dv.ToTable();

                        exportSaleItems = sync.exportTables[1];
                        if (txtView.SelectedIndex == 0)
                        {
                            FillGrid(pGet());
                            pnlMsg.Visible = false;
                        }
                        if (txtView.SelectedIndex == 1)
                        {
                            FillGridItems(pGetItem());
                            pnlMsg.Visible = false;
                        }
                        if (txtView.SelectedIndex == 2)
                        {
                            FillGridAccount(pGetAccount());
                            pnlMsg.Visible = false;
                        }
                        break;
                }

            });
        }

        void btnPrint_Click(object sender, EventArgs e)
        {
            if (grdReport.Rows.Count > 0)
            {
                PrintList();
            }
        }
        void PrintList()
        {
            PrintDocument pd = new PrintDocument();
            pd.DocumentName = lblText.Text;
            pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
            PrintDialog pdlg = new PrintDialog();
            pdlg.Document = pd;
            if (pdlg.ShowDialog() == DialogResult.OK)
            {
                PrintPreviewDialog ppdlg = new PrintPreviewDialog();
                ppdlg.Document = pd;
                ppdlg.ShowDialog();
            }
        }
        int rstLn = -1;
        int c = 1;
        void pd_PrintPage(object sender, PrintPageEventArgs e)
        {
            float lpp = 0;
            float y = 0;
            float tm = e.MarginBounds.Top;
            float lm = e.PageBounds.Left + 50;
            float lw = e.PageBounds.Width - 50;
            float th = e.PageBounds.Height - 100;
            float tHt = 0;
            Font cFont;
            StringFormat sf = new StringFormat();
            //Start Printing here
            
            y = 50;

            cFont = new Font("Courier New", 11f, FontStyle.Bold);
            
            sf.Alignment = StringAlignment.Center;
            e.Graphics.DrawString(cmbStore.Text +" - "+txtDate.Text, cFont, Brushes.Black, e.PageBounds.Width / 2, 50, sf);

            cFont = new Font("Arial", 8f, FontStyle.Regular);
            tHt = cFont.GetHeight(e.Graphics);
            y = 90;
            sf.Alignment = StringAlignment.Near;

            if (curLoaded == 0)
            {
                lpp = (th - y) / tHt;
                int i = cL, cl=0;

                while (cl <= lpp && i < dt.Rows.Count)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        int m = j % 2;
                        int xf = 0;
                        //Alignment
                        if (m == 1)
                        {
                            sf.Alignment = StringAlignment.Far;
                            xf = 50;
                        }
                        else
                        {
                            sf.Alignment = StringAlignment.Near;
                        }
                        //Header
                        if (rstLn < 1 || i == dt.Rows.Count - 1)
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Bold);
                            e.Graphics.DrawRectangle(new Pen(Brushes.Black), lm, y, lm + (60 * (dt.Columns.Count-1)), tHt);
                        }
                        else
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Regular);
                        }
                        if (rstLn >= 0)
                        {
                            rstLn = cL;

                        }
                        else
                        {
                            //rstLn = i;
                            rstLn++;

                        }

                        e.Graphics.DrawString(dt.Rows[rstLn][j].ToString(), cFont, Brushes.Black, lm + (60 * j) + xf, y, sf);
                        if ((rstLn > 1 && m == 0)) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (60 * j), y, lm + (60 * j), y + tHt);
                        if (j == dt.Columns.Count - 1) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (60 * j) + xf, y, lm + (60 * j) + xf, y + tHt);
                    }

                    y += tHt;
                    i++;
                    cl++;
                    cL++;
                }
                
            }
            if (curLoaded == 1)
            {
                lpp = (th - y) / tHt;
                int i = cL, cl = 0;
                while (cl <= lpp && i < dt.Rows.Count)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        int m = j % 2;
                        int xf = 0;
                        //Alignment
                        if (m == 1)
                        {
                            sf.Alignment = StringAlignment.Far;
                            xf = 50;
                        }
                        else
                        {
                            sf.Alignment = StringAlignment.Near;
                        }
                        //Header
                        if (i < 1)
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Bold);
                            e.Graphics.DrawRectangle(new Pen(Brushes.Black), lm, y, lm + (360 * (dt.Columns.Count - 1)), tHt);
                        }
                        else
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Regular);
                        }
                        e.Graphics.DrawString(dt.Rows[i][j].ToString(), cFont, Brushes.Black, lm + (360 * j) + xf, y, sf);
                        
                        if (i > 0 & m == 0) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (360 * j), y, lm + (360 * j), y + tHt);
                        if (j == dt.Columns.Count - 1) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (360 * j) + xf, y, lm + (360 * j) + xf, y + tHt);
                        if (i == dt.Rows.Count - 1) e.Graphics.DrawLine(new Pen(Brushes.Black), lm, y + tHt, lm + (360 * j) + xf, y + tHt);
                    }

                    y += tHt;
                    i++;
                    cl++;
                    cL++;
                }

            }
            if (curLoaded == 2)
            {
                lpp = (th - y) / tHt;
                int i = cL, cl = 0;
                while (cl <= lpp && i < dt.Rows.Count)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        int xf = 0;
                        int spc = 120;
                        //Alignment
                        if (j == 2 || j == 5)
                        {
                            sf.Alignment = StringAlignment.Far;
                            xf = 50;
                            if (j == 5) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (spc * j) + xf, y, lm + (spc * j) + xf, y + tHt);
                        }
                        else if(j == 0 || j == 3)
                        {
                            sf.Alignment = StringAlignment.Near;
                            if (j == 3) e.Graphics.DrawLine(new Pen(Brushes.Black), lm + (spc * j) + xf, y, lm + (spc * j) + xf, y + tHt);
                        }
                        //Header
                        if (i < 2)
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Bold);
                            e.Graphics.DrawRectangle(new Pen(Brushes.Black), lm, y, lm + (spc * (dt.Columns.Count - 1)), tHt);
                        }
                        else
                        {
                            cFont = new Font("Arial", 8f, FontStyle.Regular);
                        }
                        if (i > 1)
                        {
                            e.Graphics.DrawLine(new Pen(Brushes.Black), lm, y, lm, y + tHt);

                        }
                        if (i == dt.Rows.Count - 1) e.Graphics.DrawLine(new Pen(Brushes.Black), lm, y + tHt, lm + (spc * j) + xf, y + tHt);
                        if (j == 1)
                        {
                            spc = 160;
                        }
                        if (j == 4)
                        {
                            spc = 130;
                        }
                        e.Graphics.DrawString(dt.Rows[i][j].ToString(), cFont, Brushes.Black, lm + (spc * j) + xf, y, sf);
                        
                    }

                    y += tHt;
                    i++;
                    cl++;
                    cL++;
                }
            }
            //If Has more pages
            if (cL < dt.Rows.Count - 1)
            {
                e.HasMorePages = true;
                rstLn = -1;
                c = 0;
            }
            else
            {
                e.HasMorePages = false;
                cL = 0;
            }
        }

        void btnLoad_Click(object sender, EventArgs e)
        {
            pnlMsg.Visible = true;
                path.date = txtDate.Text;
                path.remNode = cmbStore.Text;
                path.fileNames.Clear();
                path.fileNames.Add("Daily Sales");
                path.fileNames.Add("Daily Sales Item");
                sync.ReadMany(path);
        }

        void FillGrid(SalesType[] dst)
        {
            //Build the columns and initialize values
            dt.Rows.Clear();
            dt.Columns.Clear();
            for (int i = 0; i < dst.Length * 2; i++)
            {
                dt.Columns.Add();
            }
            DataRow dr1 = dt.NewRow();
            for (int i = 0; i < dst.Length; i++)
            {
                dr1[i*2] = dst[i].fSalesman;
                
            }
            dt.Rows.Add(dr1);
            DataRow dr2 = dt.NewRow();
            for (int i = 0; i < dst.Length; i++)
            {
                dr2[i*2] = "Invoice #";
                dr2[(i*2) + 1] = "Amount";
                dst[i].fTotal = "0";
                grdReport.Columns[i * 2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                grdReport.Columns[(i * 2) + 1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                grdReport.Columns[i * 2].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            }
            dt.Rows.Add(dr2);
            if (grdReport.Rows.Count > 0)
            {
                grdReport.Rows[0].DefaultCellStyle.BackColor = Color.Yellow;
                grdReport.Rows[1].DefaultCellStyle.BackColor = Color.Gray;
            }
            //Load the data.
            int curL = 0;
            bool hasMore = false;
            do
            {
                DataRow dr = dt.NewRow();
                hasMore = false;
                for (int i = 0; i < dst.Length; i++)
                {
                    if (curL < dst[i].fSale.Length)
                    {
                        dr[i * 2] = dst[i].fSale[curL].fInvoice;
                        dr[(i * 2) + 1] = dst[i].fSale[curL].fAmount;
                        dst[i].fTotal = (float.Parse(dst[i].fTotal) + float.Parse(dst[i].fSale[curL].fAmount)).ToString();
                        hasMore = true;
                    }
                }
                curL++;
                if(hasMore)dt.Rows.Add(dr);
            } while (hasMore);

            DataRow dr3 = dt.NewRow();
            for (int i = 0; i < dst.Length; i++)
            {
                dr3[i * 2] = "Total";
                dr3[(i * 2) + 1] = Common.FormatCurrency(dst[i].fTotal);
            }
            dt.Rows.Add(dr3);
            if (grdReport.Rows.Count > 0)
            {
                int ind = grdReport.Rows.Count - 1;
                grdReport.Rows[ind].DefaultCellStyle.Font = new Font("Courier New", 12f, FontStyle.Bold);
            }
            curLoaded = 0;
        }
        void FillGridItems(DataTable dst)
        {
            dt = new DataTable();
            dt.Columns.Add("Description");
            dt.Columns.Add("Quantity");
            DataRow dr1 = dt.NewRow();
            dr1["Description"] = "Description";
            dr1["Quantity"] = "Quantity";
            dt.Rows.Add(dr1);
            for (int i = 0; i < dst.Rows.Count; i++)
            {
                DataRow dr = dt.NewRow();
                dr["Description"] = dst.Rows[i]["Description"];
                dr["Quantity"] = dst.Rows[i]["Quantity"];
                dt.Rows.Add(dr);
            }

            grdReport.DataSource = dt;
            if (grdReport.Rows.Count > 0)
            {
                grdReport.Rows[0].DefaultCellStyle.BackColor = Color.Yellow;
            }
            grdReport.Columns[0].Width = (grdReport.Width * 40) / 100;
            grdReport.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            curLoaded = 1;
        }
        void FillGridAccount(DataTable dst)
        {
            dt = new DataTable();
            for (int i = 0; i < 6; i++)
            {
                dt.Columns.Add();
            }
            DataRow dr1 = dt.NewRow();
            dr1[0] = "SALES";
            dr1[1] = "ACCOUNT";

            dr1[3] = "CHARGED";
            dr1[4] = "ACCOUNT";

            dt.Rows.Add(dr1);
            DataRow dr2 = dt.NewRow();
            dr2[0] = "Customer's Name";
            dr2[1] = "Invoices";
            dr2[2] = "Amount";
            dr2[3] = "Customer's Name";
            dr2[4] = "OR #";
            dr2[5] = "Amount";
            dt.Rows.Add(dr2);
            for (int i = 0; i < dst.Rows.Count; i++)
            {
                DataRow dr = dt.NewRow();
                dr[0] = dst.Rows[i][0];
                dr[1] = dst.Rows[i][1];
                dr[2] = Common.FormatCurrency(dst.Rows[i][2].ToString());
                dr[3] = dst.Rows[i][3];
                dr[4] = dst.Rows[i][4];
                dr[5] = Common.FormatCurrency(dst.Rows[i][5].ToString());
                dt.Rows.Add(dr);
            }
            grdReport.DataSource = dt;
            if (grdReport.Rows.Count > 0)
            {
                grdReport.Rows[0].DefaultCellStyle.BackColor = Color.Gray;
                grdReport.Rows[1].DefaultCellStyle.BackColor = Color.Yellow;
            }
            grdReport.Columns[0].Width = (grdReport.Width * 20) / 100;
            grdReport.Columns[3].Width = (grdReport.Width * 20) / 100;
            grdReport.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdReport.Columns[5].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            curLoaded = 2;
        }

        void panel2_EnabledChanged(object sender, EventArgs e)
        {
            if (!panel2.Enabled)
            {
                panel2.BackColor = Color.MidnightBlue;
            }
            else
            {
                panel2.BackColor = Color.RoyalBlue;
            }
        }
        void btnClose_Click(object sender, EventArgs e)
        {
            pnlForm.Dispose();
            this.Dispose();
        }
        public Panel PanelForm
        {
            get { return pnlForm; }
        }
        public void Initialize(string Title)
        {
            this.Select();
            lblText.Text = Title;
            sync.Stores();

            grdReport.DataSource = dt;
            grdReport.Font = new Font("Courier New", 12f);

            txtView.Items.Add("by Salesman");
            txtView.Items.Add("by Item");
            txtView.Items.Add("by Account");
            txtView.SelectedItem = txtView.Items[0];

            path.fileNames = new List<string>();
        }

        struct SalesType
        {
            public string fSalesman;
            public string fTotal;
            public AmountType[] fSale;
        }
        struct AmountType
        {
            public string fInvoice;
            public string fAmount;
        }

        #region display method
        DataTable pGetItem()
        {
            string[] invoice = new string[0];
            DataTable di = new DataTable();
            DataTable descriptionCollections = new DataTable();
            
            descriptionCollections = exportSaleItems.DefaultView.ToTable(true,"fDescription");
            di.Columns.Add("Description");
            di.Columns.Add("Quantity");
            
            for (int i = 0; i < descriptionCollections.Rows.Count; i++)
            {
                DataRow dr = di.NewRow();
                dr["Description"] = descriptionCollections.Rows[i]["fDescription"].ToString();
                di.Rows.Add(dr);
            }

            for (int i = 0; i < di.Rows.Count; i++)
            {
                float amt = 0f;
                for (int j = 0; j < exportSaleItems.Rows.Count; j++)
                {
                    if (exportSaleItems.Rows[j]["fDescription"].ToString().Equals(di.Rows[i]["Description"].ToString()))
                    {
                        amt += float.Parse(exportSaleItems.Rows[j]["fQty"].ToString());
                       
                    }
                }
                di.Rows[i]["Quantity"] = Common.FormatNumber(amt.ToString());
            }

            return di;
        }
        DataTable pGetAccount()
        {
            string[] inv = new string[0];
            string[] orn = new string[0];
            DataTable dc = new DataTable();
            
            for (int i = 0; i < 6; i++)
            {
                dc.Columns.Add();
            }
            DataRow [] arr = exportSales.Select(null, "fInvoiceType DESC"); ;
            DataTable db = exportSales.Clone();
            for (int i = 0; i < arr.Length; i++)
            {
                db.ImportRow(arr[i]);
            }
            int cCnt = 0;

            for (int i = 0; i < db.Rows.Count; i++)
            {
                if (db.Rows[i]["fInvoiceType"].ToString().Equals("Sales"))
                {
                    DataRow dr = dc.NewRow();
                    dr[0] = db.Rows[i]["fSoldTo"].ToString();
                    dr[1] = db.Rows[i]["fInvoice"].ToString();
                    dc.Rows.Add(dr);
                    Array.Resize<string>(ref inv, dc.Rows.Count);
                    inv[dc.Rows.Count - 1] = dr[1].ToString();
                }

                else if (db.Rows[i]["fInvoiceType"].ToString().Equals("Charged"))
                {
                    if (cCnt < dc.Rows.Count)
                    {
                        Array.Resize<string>(ref orn, dc.Rows.Count);
                        dc.Rows[cCnt][3] = db.Rows[i]["fSoldTo"].ToString();
                        dc.Rows[cCnt][4] = db.Rows[i]["fORNum"].ToString();
                        orn[cCnt] = db.Rows[i]["fInvoice"].ToString();
                        cCnt++;
                    }
                    else
                    {
                        DataRow dr = dc.NewRow();
                        dr[3] = db.Rows[i]["fSoldTo"].ToString();
                        dr[4] = db.Rows[i]["fORNum"].ToString();
                        dc.Rows.Add(dr);
                        Array.Resize<string>(ref orn, dc.Rows.Count);
                        orn[dc.Rows.Count - 1] = db.Rows[i]["fInvoice"].ToString();
                    }
                }
            }

            for (int i = 0; i < dc.Rows.Count; i++)
            {
                float amt = 0f;
                for (int j = 0; j < exportSaleItems.Rows.Count; j++)
                {
                    if (inv.Length > 0 && dc.Rows.Count <= inv.Length)
                    {
                        if (exportSaleItems.Rows[j]["fInvoice"].ToString().Equals(inv[i]))
                        {
                            amt += float.Parse(exportSaleItems.Rows[j]["fQty"].ToString()) * float.Parse(exportSaleItems.Rows[j]["fUnitPrice"].ToString());
                            dc.Rows[i][2] = amt;
                        }
                    }
                }
            }
            
            for (int i = 0; i < dc.Rows.Count; i++)
            {
                float amt = 0f;
                for (int j = 0; j < exportSaleItems.Rows.Count; j++)
                {
                    if (orn.Length > 0)
                    {
                        if (exportSaleItems.Rows[j]["fInvoice"].ToString().Equals(orn[i]))
                        {
                            amt += float.Parse(exportSaleItems.Rows[j]["fQty"].ToString()) * float.Parse(exportSaleItems.Rows[j]["fUnitPrice"].ToString());
                            dc.Rows[i][5] = amt;
                        }
                    }
                }
            }
            
            
            return dc;
        }
        SalesType [] pGet()
        {
            SalesType[] st = new SalesType[0];
            recordTable = exportSales.DefaultView.ToTable(true, new string[] { "fSalesman" });
            st = new SalesType[recordTable.Rows.Count];
            for (int i = 0; i < recordTable.Rows.Count; i++)
            {
                st[i].fSalesman = recordTable.Rows[i]["fSalesman"].ToString();
            }
            int SaleCnt = recordTable.Rows.Count;
            for (int i = 0; i < SaleCnt; i++)
            {
                int cnt = 0;
                string[] inv = new string[0];
                for (int j = 0; j < exportSales.Rows.Count; j++)
                {
                    if (st[i].fSalesman.Equals(exportSales.Rows[j]["fSalesman"].ToString()))
                    {
                        cnt++;
                        Array.Resize<string>(ref inv, cnt);
                        inv[cnt - 1] = exportSales.Rows[j]["fInvoice"].ToString();
                    }
                }
                st[i].fSale = new AmountType[cnt];
                for (int j = 0; j < cnt; j++)
                {
                    st[i].fSale[j].fInvoice = inv[j];
                }
            }
            for (int i = 0; i < SaleCnt; i++)
            {
                for (int j = 0; j < st[i].fSale.Length; j++)
                {
                    float amt = 0f;
                    for (int k = 0; k < exportSaleItems.Rows.Count; k++)
                    {
                        if (exportSaleItems.Rows[k]["fInvoice"].ToString().Equals(st[i].fSale[j].fInvoice))
                        {
                            amt += float.Parse(exportSaleItems.Rows[k]["fQty"].ToString()) * float.Parse(exportSaleItems.Rows[k]["fUnitPrice"].ToString());
                        }
                        st[i].fSale[j].fAmount = Common.FormatCurrency(amt.ToString());
                    }
                }
            }
            return st;
        }
        #endregion
    }
}
